package com.hopes.bizz.risk.control.evaluate;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hopes.bizz.risk.control.bo.NegatedItem;
import com.hopes.bizz.risk.control.bo.RiskEffectEvaluationScore;
import com.hopes.bizz.risk.control.bo.RiskEvaluateBo;
import com.hopes.bizz.risk.control.entity.RiskControlMeasureEntity;
import com.hopes.bizz.risk.control.entity.RiskObjectEntity;
import com.hopes.bizz.risk.control.entity.RiskUnitEntity;
import com.hopes.bizz.risk.control.service.RiskControlMeasureService;
import com.hopes.bizz.risk.control.service.RiskMeasureTaskConfigService;
import com.hopes.bizz.risk.control.service.RiskObjectService;
import com.hopes.bizz.risk.control.service.RiskUnitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author lyb
 * @version 1.0
 * @description: 计算各安全风险分析对象中管控措施数量或隐患排查内容数量去重后小于10条且管控措施类型未全部包含4种类型
 * @date 2023/7/5
 */

@Component
@Slf4j
@Order(1002)
public class RiskNumberRejectFactorHandler extends RiskRejectFactorHandler {

    @Resource
    private RiskControlMeasureService riskControlMeasureService;

    @Resource
    private RiskObjectService riskObjectService;

    @Resource
    private RiskMeasureTaskConfigService riskMeasureTaskConfigService;

    @Resource
    private RiskUnitService riskUnitService;

    @Override
    protected NegatedItem doCalculate(RiskEvaluateBo riskEvaluateBo, NegatedItem negatedItem) {
        List<RiskObjectEntity> riskObjects = riskObjectService.list();
        StringBuilder sb = new StringBuilder();
        boolean score = Boolean.TRUE;
        for (RiskObjectEntity riskObject : riskObjects) {
            String hazardName = riskObject.getHazardName();
            List<RiskUnitEntity> riskUnitList = getRiskUnitByRiskObjectId(riskObject.getId());
            if (CollectionUtil.isEmpty(riskUnitList)) {
                score = Boolean.FALSE;
                sb.append(hazardName).append(" 风险对象未绑定单元;").append(LINE_SEPARATOR);
                continue;
            }
            List<Long> riskUnitIdList = riskUnitList.stream().map(RiskUnitEntity::getId).collect(Collectors.toList());
            List<RiskControlMeasureEntity> riskControlMeasures = riskControlMeasureService.getByRiskUnitIdList(riskUnitIdList);
            if (riskControlMeasures.size() < 10) {
                sb.append(hazardName).append(" 风险对象管控措施数量小于10;").append(LINE_SEPARATOR);
                score = Boolean.FALSE;
            }
            Map<String, List<RiskControlMeasureEntity>> classisfyGroupMap = riskControlMeasures.stream().filter(it -> it.getClassify1() != null).collect(Collectors.groupingBy(RiskControlMeasureEntity::getClassify1));
            if (classisfyGroupMap.size() < 4) {
                sb.append(hazardName).append(" 风险对象管控措施未覆盖所有(工程技术、维护保养、操作行为、应急措施)4种类型;").append(LINE_SEPARATOR);
                score = Boolean.FALSE;
            }

            Long count = riskMeasureTaskConfigService.countByRiskUnitIdList(riskUnitIdList);
            if (count < 10) {
                sb.append(hazardName).append(" 风险对象的隐患排查内容数量是").append(count).append(",少于10条").append(LINE_SEPARATOR);
                score = Boolean.FALSE;
            }
        }
        negatedItem.setNegatedItemTwo(score);
        if (!score) {
            negatedItem.setNegatedItemTwoReason(sb.toString());
        }
        return doNextCalculate(riskEvaluateBo, negatedItem);
    }

    @Override
    protected Boolean isUse(RiskEffectEvaluationScore riskEffectEvaluationScore) {
        return riskEffectEvaluationScore.getRiskObjectNumberFlag();
    }

    private List<RiskUnitEntity> getRiskUnitByRiskObjectId(Long riskObjectId) {
        LambdaQueryWrapper<RiskUnitEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(RiskUnitEntity::getRiskObjectId, riskObjectId);
        return riskUnitService.list(wrapper);
    }
}
